package cc.uncarbon.module.appapi.service;

import cc.uncarbon.framework.core.constant.HelioConstant;
import cc.uncarbon.framework.core.context.UserContextHolder;
import cc.uncarbon.framework.core.exception.BusinessException;


import cc.uncarbon.module.appapi.mapper.BookBydMapper;
import cc.uncarbon.module.appapi.model.request.AdminBookBydInsertOrUpdateDTO;

import cc.uncarbon.module.appapi.model.response.BydBO;
import cc.uncarbon.module.appapi.model.vo.BydVO;
import cn.hutool.core.bean.BeanUtil;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.yanrumiao.entity.BookBydEntity;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 加油记录
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class BookBydService {

    private final BookBydMapper bookBydMapper;


    /**
     * 列表
     */


    /**
     * 根据 ID 取详情
     *
     * @param id 主键ID
     * @return null or BO
     */
    public BydBO getOneById(Long id) {
        return this.getOneById(id, false);
    }

    /**
     * 根据 ID 取详情
     *
     * @param id               主键ID
     * @param throwIfInvalidId 是否在 ID 无效时抛出异常
     * @return null or BO
     */
    public BydBO getOneById(Long id, boolean throwIfInvalidId) throws BusinessException {
        BookBydEntity entity = bookBydMapper.selectById(id);
        if (throwIfInvalidId && entity == null) {
            throw new BusinessException(400, "无效加油记录ID");
        }

        return this.entity2BO(entity);
    }

    /**
     * 后台管理-新增
     */
    @Transactional(rollbackFor = Exception.class)
    public Long adminInsert(AdminBookBydInsertOrUpdateDTO dto) {
        log.info("[后台管理-加油记录-新增] >> DTO={}", dto);
        this.checkExistence(dto);

        dto.setId(null);
        BookBydEntity entity = new BookBydEntity();
        BeanUtil.copyProperties(dto, entity);

        bookBydMapper.insert(entity);

        return entity.getId();
    }

    /**
     * 后台管理-编辑
     */
    @Transactional(rollbackFor = Exception.class)
    public void adminUpdate(AdminBookBydInsertOrUpdateDTO dto) {
        log.info("[后台管理-加油记录-编辑] >> DTO={}", dto);
        this.checkExistence(dto);

        BookBydEntity entity = new BookBydEntity();
        BeanUtil.copyProperties(dto, entity);

        bookBydMapper.updateById(entity);
    }

    /**
     * 后台管理-删除
     */
    @Transactional(rollbackFor = Exception.class)
    public void adminDelete(Collection<Long> ids) {
        log.info("[后台管理-加油记录-删除] >> ids={}", ids);
        bookBydMapper.deleteByIds(ids);
    }


    /*
    ----------------------------------------------------------------
                        私有方法 private methods
    ----------------------------------------------------------------
     */

    /**
     * 实体转 BO
     *
     * @param entity 实体
     * @return BO
     */
    private BydBO entity2BO(BookBydEntity entity) {
        if (entity == null) {
            return null;
        }

        BydBO bo = new BydBO();
        BeanUtil.copyProperties(entity, bo);

        // 可以在此处为BO填充字段

        return bo;
    }

    /**
     * 实体 List 转 BO List
     *
     * @param entityList 实体 List
     * @return BO List
     */


    /**
     * 检查是否已存在同名数据
     *
     * @param dto DTO
     */
    private void checkExistence(AdminBookBydInsertOrUpdateDTO dto) {
        /*
        可以根据自己业务需要，解禁这段代码，修改判断条件和文案

        BookBydEntity existingEntity = bookBydMapper.selectOne(
                new QueryWrapper<BookBydEntity>()
                        .lambda()
                        .select(BookBydEntity::getId)
                        .eq(BookBydEntity::getTitle, dto.getTitle())
                        .last(HelioConstant.CRUD.SQL_LIMIT_1)
        );

        if (existingEntity != null && !existingEntity.getId().equals(dto.getId())) {
            throw new BusinessException(400, "已存在相同加油记录，请重新输入");
        }
        */
    }

    public BydVO appList() {
        List<BookBydEntity> bookBydEntities = bookBydMapper.selectList(null);
        ArrayList<BydBO> bydBOList = new ArrayList<>();
        bookBydEntities.stream().forEach(entity -> {
            BydBO bydBO = this.entity2BO(entity);
            bydBOList.add(bydBO);
        });
        QueryWrapper<BookBydEntity> queryWrapper1 = new QueryWrapper<>();

        queryWrapper1.select("SUM(money) as count");
        List<Map<String, Object>> selectMaps = bookBydMapper.selectMaps(queryWrapper1);
        BydVO bydVO = new BydVO();

        bydVO.setList(bydBOList);
        if(selectMaps != null && !selectMaps.isEmpty()){
            Map<String, Object> resultMap = selectMaps.get(0);
            if(resultMap != null){
                bydVO.setCount((BigDecimal) resultMap.get("count"));
            }else{
                bydVO.setCount(new BigDecimal("0"));
            }
        }

        return bydVO;
    }
}
